using System;
using System.Globalization;
using System.IO;
using System.Numerics;
using ns15;
using ns20;

namespace Newtonsoft.Json.Bson
{
	public class BsonWriter : JsonWriter
	{
		private readonly Class68 class68_0;

		private Class71 class71_0;

		private Class71 class71_1;

		private string string_1;

		public DateTimeKind DateTimeKindHandling
		{
			get
			{
				return class68_0.DateTimeKind_0;
			}
			set
			{
				class68_0.DateTimeKind_0 = value;
			}
		}

		public BsonWriter(Stream stream)
		{
			Class204.smethod_2(stream, "stream");
			class68_0 = new Class68(new BinaryWriter(stream));
		}

		public BsonWriter(BinaryWriter writer)
		{
			Class204.smethod_2(writer, "writer");
			class68_0 = new Class68(writer);
		}

		public override void Flush()
		{
			class68_0.method_0();
		}

		protected override void WriteEnd(JsonToken token)
		{
			base.WriteEnd(token);
			method_21();
			if (base.Top == 0)
			{
				class68_0.method_2(class71_0);
			}
		}

		public override void WriteComment(string text)
		{
			throw JsonWriterException.smethod_1(this, "Cannot write JSON comment as BSON.", null);
		}

		public override void WriteStartConstructor(string name)
		{
			throw JsonWriterException.smethod_1(this, "Cannot write JSON constructor as BSON.", null);
		}

		public override void WriteRaw(string json)
		{
			throw JsonWriterException.smethod_1(this, "Cannot write raw JSON as BSON.", null);
		}

		public override void WriteRawValue(string json)
		{
			throw JsonWriterException.smethod_1(this, "Cannot write raw JSON as BSON.", null);
		}

		public override void WriteStartArray()
		{
			base.WriteStartArray();
			method_20(new Class73());
		}

		public override void WriteStartObject()
		{
			base.WriteStartObject();
			method_20(new Class72());
		}

		public override void WritePropertyName(string name)
		{
			base.WritePropertyName(name);
			string_1 = name;
		}

		public override void Close()
		{
			base.Close();
			if (base.CloseOutput && class68_0 != null)
			{
				class68_0.method_1();
			}
		}

		private void method_20(Class71 class71_2)
		{
			method_23(class71_2);
			class71_1 = class71_2;
		}

		private void method_21()
		{
			class71_1 = class71_1.Class71_0;
		}

		private void method_22(object object_0, Enum11 enum11_0)
		{
			method_23(new Class74(object_0, enum11_0));
		}

		internal void method_23(Class71 class71_2)
		{
			if (class71_1 != null)
			{
				if (class71_1 is Class72)
				{
					((Class72)class71_1).method_0(string_1, class71_2);
					string_1 = null;
				}
				else
				{
					((Class73)class71_1).method_0(class71_2);
				}
				return;
			}
			if (class71_2.Enum11_0 != Enum11.Object && class71_2.Enum11_0 != Enum11.Array)
			{
				throw JsonWriterException.smethod_1(this, "Error writing {0} value. BSON must start with an Object or Array.".smethod_0(CultureInfo.InvariantCulture, class71_2.Enum11_0), null);
			}
			class71_1 = class71_2;
			class71_0 = class71_2;
		}

		public override void WriteValue(object value)
		{
			if (value is BigInteger)
			{
				method_17(JsonToken.Integer);
				method_23(new Class76(((BigInteger)value).ToByteArray(), Enum9.Binary));
			}
			else
			{
				base.WriteValue(value);
			}
		}

		public override void WriteNull()
		{
			base.WriteNull();
			method_22(null, Enum11.Null);
		}

		public override void WriteUndefined()
		{
			base.WriteUndefined();
			method_22(null, Enum11.Undefined);
		}

		public override void WriteValue(string value)
		{
			base.WriteValue(value);
			if (value == null)
			{
				method_22(null, Enum11.Null);
			}
			else
			{
				method_23(new Class75(value, includeLength: true));
			}
		}

		public override void WriteValue(int value)
		{
			base.WriteValue(value);
			method_22(value, Enum11.Integer);
		}

		[CLSCompliant(false)]
		public override void WriteValue(uint value)
		{
			if (value > int.MaxValue)
			{
				throw JsonWriterException.smethod_1(this, "Value is too large to fit in a signed 32 bit integer. BSON does not support unsigned values.", null);
			}
			base.WriteValue(value);
			method_22(value, Enum11.Integer);
		}

		public override void WriteValue(long value)
		{
			base.WriteValue(value);
			method_22(value, Enum11.Long);
		}

		[CLSCompliant(false)]
		public override void WriteValue(ulong value)
		{
			if (value > long.MaxValue)
			{
				throw JsonWriterException.smethod_1(this, "Value is too large to fit in a signed 64 bit integer. BSON does not support unsigned values.", null);
			}
			base.WriteValue(value);
			method_22(value, Enum11.Long);
		}

		public override void WriteValue(float value)
		{
			base.WriteValue(value);
			method_22(value, Enum11.Number);
		}

		public override void WriteValue(double value)
		{
			base.WriteValue(value);
			method_22(value, Enum11.Number);
		}

		public override void WriteValue(bool value)
		{
			base.WriteValue(value);
			method_22(value, Enum11.Boolean);
		}

		public override void WriteValue(short value)
		{
			base.WriteValue(value);
			method_22(value, Enum11.Integer);
		}

		[CLSCompliant(false)]
		public override void WriteValue(ushort value)
		{
			base.WriteValue(value);
			method_22(value, Enum11.Integer);
		}

		public override void WriteValue(char value)
		{
			base.WriteValue(value);
			string text = null;
			text = value.ToString(CultureInfo.InvariantCulture);
			method_23(new Class75(text, includeLength: true));
		}

		public override void WriteValue(byte value)
		{
			base.WriteValue(value);
			method_22(value, Enum11.Integer);
		}

		[CLSCompliant(false)]
		public override void WriteValue(sbyte value)
		{
			base.WriteValue(value);
			method_22(value, Enum11.Integer);
		}

		public override void WriteValue(decimal value)
		{
			base.WriteValue(value);
			method_22(value, Enum11.Number);
		}

		public override void WriteValue(DateTime value)
		{
			base.WriteValue(value);
			value = Class185.smethod_2(value, base.DateTimeZoneHandling);
			method_22(value, Enum11.Date);
		}

		public override void WriteValue(DateTimeOffset value)
		{
			base.WriteValue(value);
			method_22(value, Enum11.Date);
		}

		public override void WriteValue(byte[] value)
		{
			base.WriteValue(value);
			method_23(new Class76(value, Enum9.Binary));
		}

		public override void WriteValue(Guid value)
		{
			base.WriteValue(value);
			method_23(new Class76(value.ToByteArray(), Enum9.Uuid));
		}

		public override void WriteValue(TimeSpan value)
		{
			base.WriteValue(value);
			method_23(new Class75(value.ToString(), includeLength: true));
		}

		public override void WriteValue(Uri value)
		{
			base.WriteValue(value);
			method_23(new Class75(value.ToString(), includeLength: true));
		}

		public void WriteObjectId(byte[] value)
		{
			Class204.smethod_2(value, "value");
			if (value.Length != 12)
			{
				throw JsonWriterException.smethod_1(this, "An object id must be 12 bytes", null);
			}
			method_0();
			method_11(JsonToken.Undefined);
			method_22(value, Enum11.Oid);
		}

		public void WriteRegex(string pattern, string options)
		{
			Class204.smethod_2(pattern, "pattern");
			method_0();
			method_11(JsonToken.Undefined);
			method_23(new Class77(pattern, options));
		}
	}
}
